from PySide6.QtCore import QDateTime, Slot, Qt, QTimer
from PySide6.QtWidgets import QMessageBox, QDialog, QTableWidgetItem, QMainWindow, QButtonGroup
from PySide6.QtGui import QIcon, QColor

from Devices.DeviceWindow import DeviceWindow
from Devices.Chiot.BsDevs.ComDev.ComDev import ComDev
from Devices.Chiot.BsDevs.ComDev.ComDevParser import ComDevParser
from Components.MessageBoxFunc import MessageBoxFunc

LOG_COLOR_BLACK   =   "\033[0;30m"
LOG_COLOR_RED     =   "\033[0;31m"
LOG_COLOR_GREEN   =   "\033[0;32m"
LOG_COLOR_YELLOW  =   "\033[0;33m"
LOG_COLOR_BLUE    =   "\033[0;34m"
LOG_COLOR_MAGENTA =   "\033[0;35m"
LOG_COLOR_CYAN    =   "\033[0;36m"
LOG_COLOR_WHITE   =   "\033[0;37m"
LOG_COLOR_RESET   =   "\033[0m"

class ComDevWindow(DeviceWindow):
    # 0.界面
    def __init__(self, supportDevice, parent = None):
        super().__init__(supportDevice, parent)
        self.__ComFullStatus = ComDev.FullStatus()

        self.__LogData = ""

    def testUi(self):
        self._ui.label_mac.setText("1234")
        self._ui.label_firmwareVersion.setText("123")
        self._ui.label_hardwareVersion.setText("123")
        self._ui.label_protocol.setText("123")
        self._ui.label_modelId.setText("123")
        self._ui.label_heartbeatFreq.setText("123")
        self._ui.label_wifiSsid.setText("123")
        self._ui.label_wifiRssi.setText("123")
        self._ui.label_wifiBssid.setText("123")

        self._ui.label_serverType.setText("123")
        self._ui.label_bindStatus.setText("123")
        self._ui.label_mqttStatus.setText("123")
        self._ui.label_chipType.setText("123")
        self._ui.label_serialNum.setText("123")
        self._ui.label_buildTime.setText("123")
        self._ui.label_timezone.setText("123")
        self._ui.label_nowTimestamp.setText("123")

    def initUiWindow(self):
        self._HttpServerWindow.SetLogServerEnable(False)
        self._OtaUrl = self._ui.lineEdit_downloadUrl.text()

        # 设置设备详情页 默认项（0-设备详情 1-开关控制 ...）
        self._ui.tabWidget.setCurrentIndex(0)
        self._ui.progressBar_Ota.setVisible(False)
        
        self._ui.pushButton_Log.clicked.connect(self.on_pushButton_Log_clicked)
        self._ui.pushButton_SendCmd.clicked.connect(self.on_pushButton_SendCmd_clicked)
        self._ui.pushButton_Messages.clicked.connect(self.on_pushButton_Messages_clicked)
        self._ui.pushButton_Http.clicked.connect(self.on_pushButton_Http_clicked)

    """ 
    colors_map = (("\033[0;30m", Qt.black), 
                      ("\033[0;31m", Qt.red), 
                      ("\033[0;32m", QColor.fromRgb(0, 170, 0)), #GREEN
                      ("\033[0;33m", QColor.fromRgb(255, 180, 0)), #YELLOW
                      ("\033[0;34m", Qt.blue), 
                      ("\033[0;35m", Qt.darkMagenta), 
                      ("\033[0;36m", Qt.darkCyan), 
                      ("\033[0m", Qt.black))
    """
    def addLogColor(self, log):
        log_string = log.strip()
        if 0 == len(log_string):
            return
        first_letter = log_string[0]

        color_fmt = LOG_COLOR_BLACK
        if "[I]" in log_string or "I" == first_letter:
            color_fmt = LOG_COLOR_GREEN
        elif "[D]" in log_string or "D" == first_letter:
            color_fmt = LOG_COLOR_BLUE
        elif "[W]" in log_string or "W" == first_letter:
            color_fmt = LOG_COLOR_YELLOW
        elif "[E]" in log_string or "E" == first_letter:
            color_fmt = LOG_COLOR_RED

        self._LogWindow.AddLog(color_fmt + log_string + LOG_COLOR_RESET)
        self.LogDateReceived(log_string)

    def on_LogDateReceived(self, data):
        self.__LogData += data
        logData = ""
        while '\n' in self.__LogData:
            logData, self.__LogData = self.__LogData.split('\n', 1)
            self.addLogColor(logData)

    # 1.设备连接
    def VerifyConnect(self, cmdPort, logPort):
        self.cmdPort = cmdPort
        self.logPort = logPort
        super().VerifyConnect(cmdPort, logPort)
        self._ui.lineEdit_downloadUrl.setText(self._OtaUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort(), self._SupportDevice.deviceBinName))
        
        cmd = ComDevParser.PackGetVerify()
        self.SendCommandText(cmd)

    def Connected(self, ip, port):
        # self.ShowMessageBox("设备连接", "日志端口连接成功!")
        cmd = ComDevParser.PackGetFullStatus()
        self.SendCommandText(cmd)
    
    def DisConnected(self):
        self.ShowMessageBox("设备断开连接", "")

    # 2.接收消息解析处理
    def SetDeviceFullStatus(self, msgValue):
        if ComDevParser.ParseFullStatus(msgValue, self.__ComFullStatus):
            #基本信息
            self._ui.label_mac.setText(self.__ComFullStatus.mac)
            self._ui.label_firmwareVersion.setText(self.__ComFullStatus.firmwareVersion)
            self._ui.label_hardwareVersion.setText(self.__ComFullStatus.hardwareVersion)

            self._ui.label_protocol.setText(self.__ComFullStatus.protocol)
            self._ui.label_modelId.setText(self.__ComFullStatus.modelId)
            if ComDev.ServerType.CN_NORMAL == self.__ComFullStatus.serverType:
                self._ui.label_serverType.setText("国内正式(旧)")
            elif ComDev.ServerType.OVERSEA_NORMAL == self.__ComFullStatus.serverType:
                self._ui.label_serverType.setText("海外正式(旧)")
            elif ComDev.ServerType.OVERSEA_DEVELOP == self.__ComFullStatus.serverType:
                self._ui.label_serverType.setText("开发(旧)")
            elif ComDev.ServerType.BUSINESS_OVERSEA_NORMAL == self.__ComFullStatus.serverType:
                self._ui.label_serverType.setText("商用海外正式")
            elif ComDev.ServerType.BUSINESS_DEVELOP == self.__ComFullStatus.serverType:
                self._ui.label_serverType.setText("商用开发")
            elif ComDev.ServerType.LOCAL_DEMO == self.__ComFullStatus.serverType:
                self._ui.label_serverType.setText("局域网演示")
            else:
                self._ui.label_serverType.setText("未知类型(%d)" % (self.__ComFullStatus.serverType))

            self._ui.label_heartbeatFreq.setText("%d秒" % (self.__ComFullStatus.heartbeatFreq))
            self._ui.label_timezone.setText(self.__ComFullStatus.timezone)
            self._ui.label_nowTimestamp.setText(QDateTime.fromSecsSinceEpoch(self.__ComFullStatus.nowTimestamp).toString("yyyy-MM-dd HH:mm:ss"))
            
            self._ui.label_chipType.setText(self.__ComFullStatus.chipType)
            self._ui.label_serialNum.setText(self.__ComFullStatus.serialNum)
            self._ui.label_buildTime.setText(self.__ComFullStatus.buildTime)
                
            self._ui.label_wifiSsid.setText(self.__ComFullStatus.wifiSsid)
            self._ui.label_wifiRssi.setText(self.__ComFullStatus.wifiRssi)
            self._ui.label_wifiBssid.setText(self.__ComFullStatus.wifiBssid)

            self._ui.label_bindStatus.setText("已绑定" if self.__ComFullStatus.bindStatus else "未绑定")
            self._ui.label_mqttStatus.setText("已连接" if self.__ComFullStatus.mqttStatus else "未连接")

            if ComDev.ServerType.CN_NORMAL <= (self.__ComFullStatus.serverType) <= ComDev.ServerType.LOCAL_DEMO:
                self._ui.comboBox_serverType.blockSignals(True)
                self._ui.comboBox_serverType.setCurrentIndex(self.__ComFullStatus.serverType - 1)
                self._ui.comboBox_serverType.blockSignals(False)

    def CmdRptCustomReceived(self, msgValue):
        pass

    def CmdRptStatusReceived(self, msgValue):
        pass

    def CmdHeartbeatReceived(self, msgValue):
        pass

    def CmdFullStatusReceived(self, msgValue):
        pass

    def CmdMsgValueReceived(self, msgName, msgValue):
        pass

    def CmdDateReceived(self, data):
        ret, msgName, msgValue = ComDevParser.ParseMsg(data)
        if not ret:
            return
        
        self.CmdMsgValueReceived(msgName, msgValue)
        if msgName == "deviceVerify2":
            verify = msgValue["verify"]
            cmd = ComDevParser.PackGetVerifyRsp(verify)
            self.SendCommandText(cmd)

            self.LogConnect(self.cmdPort, self.logPort)
            self._ui.lineEdit_downloadUrl.setText(self._OtaUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort(), self._SupportDevice.deviceBinName))
            # self.ShowMessageBox("设备认证", "成功!")
        elif msgName == "getFullStatus":
            self.SetDeviceFullStatus(msgValue)
            self.CmdFullStatusReceived(msgValue)
        elif msgName == "heartbeat":
            self.SetDeviceFullStatus(msgValue)
            self.CmdHeartbeatReceived(msgValue)
            self.ShowMessageBox("全量工况获取", "")
        elif msgName == "rptStatus":
            self.CmdRptStatusReceived(msgValue)
            # self.ShowMessageBox("设备状态变化", "")
        elif msgName == "rptCustom":
            self.CmdRptCustomReceived(msgValue)
            # self.ShowMessageBox("设备状态变化", "")
        elif msgName == "setAdcParam":
            ret = int(msgValue["ret"])
            self.ShowMessageBox("设置ADC参数", "%s!" % ("成功" if ret != 0 else "失败"), QMessageBox.Information if ret != 0 else QMessageBox.Critical)
        elif msgName == "setWiFi":
            ret = int(msgValue["ret"])
            self.ShowMessageBox("设置Wi-Fi", "%s!" % ("成功" if ret != 0 else "失败"), QMessageBox.Information if ret != 0 else QMessageBox.Critical)
        elif msgName == "setChcloudType":
            ret = int(msgValue["ret"])
            self.ShowMessageBox("设置服务器类型", "%s!" % ("成功" if ret != 0 else "失败"), QMessageBox.Information if ret != 0 else QMessageBox.Critical)
        elif msgName == "commandReply":
            ret = int(msgValue["code"])
            # self.ShowMessageBox("设置属性/配置", "%s!" % ("成功" if ret == 0 else "失败"), QMessageBox.Information if ret == 0 else QMessageBox.Critical)
        elif msgName == "otaResult":
            otaResult = ComDev.OtaResult()
            self._ui.progressBar_Ota.setVisible(False)
            if False == ComDevParser.ParseOtaResult(msgValue, otaResult):
                print("OtaResult parse error.")
                return

            #1成功 0失败
            if otaResult.result == 0:
                self.ShowMessageBox("设备升级结果", "失败原因:"+otaResult.failReason, QMessageBox.Critical, timeoutMs=5000)
            else:
                self.ShowMessageBox("设备升级结果", "成功"+otaResult.failReason, QMessageBox.Information, timeoutMs=5000)

        elif msgName == "otaProcess":
            otaProcess = ComDev.OtaProcess()
            if False == ComDevParser.ParseOtaProcess(msgValue, otaProcess):
                print("OtaProcess parse error.")
                return

            if len(otaProcess.totalTime):
                startTime = int(otaProcess.startTime) if len(otaProcess.startTime) else 0
                if 0 != startTime:
                    startDateTime = QDateTime.fromMSecsSinceEpoch(startTime).toString("yyyy-MM-dd HH:mm:ss")
                    self.ShowMessageBox("设备升级", "\r\n开始时间\"%s\",预计用时%d秒!" % (startDateTime, int(otaProcess.totalTime)))
            
            if len(otaProcess.progress):
                progress = int(otaProcess.progress) if len(otaProcess.progress) else 0
                self._ui.progressBar_Ota.setVisible(True)
                self._ui.progressBar_Ota.setValue(progress)
                if (100 == progress):
                    self.ReConnect()
                    self._ui.progressBar_Ota.setVisible(False)

            if len(otaProcess.process):
                process = int(otaProcess.process) if len(otaProcess.process) else 0
                # 0等待升级 3正在升级
                if process == 0 or process == 3: 
                    self._ui.progressBar_Ota.setVisible(True)
                    # self.ShowMessageBox("设备升级", "正在升级", QMessageBox.Information, timeoutMs=5000)
                # 1安装固件 2升级完成
                elif process == 1 or process == 2:
                    self._ui.progressBar_Ota.setVisible(False)
                    self.ShowMessageBox("设备升级结果", "升级完成,等待重启.请重新连接设备！！！", QMessageBox.Information, timeoutMs=5000)
                    self.ReConnect()
                # -1升级失败
                elif process < 0:
                    self._ui.progressBar_Ota.setVisible(False)
                    self.ShowMessageBox("设备升级结果", "升级失败", QMessageBox.Critical, timeoutMs=5000)
                

    # 3.菜单栏
    @Slot()
    def on_pushButton_Sync_clicked(self):
        """
        同步设备信息
        """
        cmd = ComDevParser.PackGetFullStatus()
        self.SendCommandText(cmd)
    
    # 4. 调试页面
    @Slot()
    def on_pushButton_setTimezone_clicked(self):
        cmd = ComDevParser.PackSetTimezone(self._ui.comboBox_timezone.currentText())
        self.SendCommandText(cmd)
    
    @Slot()
    def on_pushButton_setServerType_clicked(self):
        cmd = ComDevParser.PackSetCloudType(self._ui.comboBox_serverType.currentIndex()+1)
        self.SendCommandText(cmd)
    
    @Slot()
    def on_pushButton_sendWiFi_clicked(self):
        if 0 == len(self._ui.lineEdit_SSID.text()):
            MessageBoxFunc.ShowMessageBox("Wi-Fi设置","SSID不能为空!", self, QMessageBox.Warning)
        else:
            cmd = ComDevParser.PackSetWiFi(self._ui.lineEdit_SSID.text(), self._ui.lineEdit_Password.text())
            self.SendCommandText(cmd)

    @Slot()
    def on_pushButton_upgrade_clicked(self):
        packageId = "123123" if 0 == len(self._ui.lineEdit_upgradePackageId.text()) else self._ui.lineEdit_upgradePackageId.text()
        cmd = ComDevParser.PackUpgrade(packageId, self._ui.lineEdit_downloadUrl.text(), self._ui.label_mac.text(), self._ui.lineEdit_newVersion.text(), self._ui.lineEdit_md5.text(), self._ui.lineEdit_size.text())
        self.SendCommandText(cmd)
        self._ui.progressBar_Ota.setVisible(True)
        self._ui.progressBar_Ota.setValue(0)

    def HttpStarted(self):
        self._ui.lineEdit_downloadUrl.setText(self._OtaUrl % (self._HttpServerWindow.GetIP(), self._HttpServerWindow.GetPort(), self._SupportDevice.deviceBinName))

    # 定时器
    def SetTimerToList(self, timer):
        rowCount = self._ui.tableWidget_timers.rowCount()
        self._ui.tableWidget_timers.insertRow(rowCount)

        self._ui.tableWidget_timers.setItem(rowCount, 0, QTableWidgetItem(timer.id))
        item = QTableWidgetItem(("启用" if timer.enable else "未启用"))
        item.setForeground(QColor.fromRgb(0, 170, 0) if timer.enable else Qt.red)
        self._ui.tableWidget_timers.setItem(rowCount, 1, item)
        self._ui.tableWidget_timers.setItem(rowCount, 2, QTableWidgetItem(QTableWidgetItem(timer.GetServiceString())))
        self._ui.tableWidget_timers.setItem(rowCount, 3, QTableWidgetItem(QTableWidgetItem(timer.start)))
        self._ui.tableWidget_timers.setItem(rowCount, 4, QTableWidgetItem(QTableWidgetItem(timer.end)))
        self._ui.tableWidget_timers.setItem(rowCount, 5, QTableWidgetItem(QTableWidgetItem(timer.GetWeekString())))
        for i in range(5):
            self._ui.tableWidget_timers.resizeColumnToContents(i)

    @Slot()
    def on_pushButton_unbind_clicked(self):
        cmd = ComDevParser.PackUnbind(self._ui.label_mac.text())
        self.SendCommandText(cmd)
    
    def ShowMessageBox(self, title, content, icon = QMessageBox.Icon.Information, timeoutMs=1000):
        MessageBoxFunc.ShowMessageBox(title, self._OriginalTitle + self._DeviceIP + content, self, icon, timeoutMs)

